package org.mspring.platform.config;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.mspring.platform.config.dao.ConfigDao;
import org.mspring.platform.config.entity.Config;
import org.mspring.platform.security.SecurityUtils;
import org.mspring.platform.security.entity.User;
import org.mspring.platform.security.exception.UNLoginException;
import org.mspring.platform.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Gao Youbo
 * @since 2014年4月13日
 */
@Service
@Transactional
public class ConfigService {

    @Autowired
    private ConfigDao configDao;
    @Autowired
    private ConfigCacheService configCacheService;

    @PostConstruct
    public void initTable() throws IOException {
        configDao.initTable();
    }

    public Config get(long id) {
        return configDao.get(id);
    }

    public String getConfig(String name) {
        Config config = getCachedConfig(name);
        if (config != null) {
            return config.getValue();
        }
        return null;
    }

    public Map<String, String> getConfigs() {
        Map<String, String> result = configCacheService.getAllCache();
        if (result != null) {
            return result;
        } else {
            result = new HashMap<>();
        }
        List<Config> configs = configDao.listAll();
        if (configs == null) {
            return result;
        }
        for (Config config : configs) {
            result.put(config.getName(), config.getValue());
        }
        configCacheService.putAllCache(result);
        return result;
    }

    private Config getCachedConfig(String name) {
        if (name == null) {
            return null;
        }
        Config config = configCacheService.get(name);
        if (config == null) {
            config = findByName(name);
            if (config != null) {
                configCacheService.put(name, config);
            }
        }
        return config;
    }

    public void setConfig(String name, Object value) throws UNLoginException {
        if (name == null || value == null) {
            return;
        }
        Config config = findByName(name);
        if (config == null) {
            config = new Config();
            this.create(name, value.toString());
        } else {
            config.setValue(value.toString());
            this.update(config);
        }
    }

    public void setConfigs(Map<String, String> configs) throws UNLoginException {
        for (Map.Entry<String, String> entry : configs.entrySet()) {
            setConfig(entry.getKey(), entry.getValue());
        }
    }

    public Config create(String name, String value) throws UNLoginException {
        Config config = new Config();
        config.setName(name);
        config.setValue(value);
        return create(config);
    }

    public Config create(Config config) throws UNLoginException {
        User user = SecurityUtils.getCurrentUser();
        if (user == null) {
            throw new UNLoginException();
        }
        config.setCreateTime(new Date());
        config.setCreateUser(user.getAlias());
        config.setCreateUserId(user.getId());
        config.setUpdateUser(user.getAlias());
        config.setUpdateUserId(user.getId());
        config.setUpdateTime(new Date());
        long id = configDao.insert(config);
        // 清理缓存
        configCacheService.removeAllCache();
        return get(id);
    }

    public void update(Config config) throws UNLoginException {
        User user = SecurityUtils.getCurrentUser();
        if (user == null) {
            throw new UNLoginException();
        }
        config.setUpdateUser(user.getAlias());
        config.setUpdateUserId(user.getId());
        config.setUpdateTime(new Date());
        configDao.update(config);

        // 清理缓存
        configCacheService.removeAllCache();
        configCacheService.remove(config.getName());
    }

    public void deleteByName(String name) {
        configDao.deleteByName(name);

        // 清理缓存
        configCacheService.removeAllCache();
        configCacheService.remove(name);
    }

    private Config findByName(String name) {
        if (StringUtils.isBlank(name)) {
            return null;
        }
        return configDao.findByName(name);
    }

}
